package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Matrix;
	import flash.net.URLRequest;
	import flash.system.ImageDecodingPolicy;
	import flash.system.LoaderContext;
	
	
	/**
	 * ImageSprite is a class to represent the loading and drawing of a single
	 * image object onto a sprite-based interface, such as Render.
	 * General use is to first call setPosition() to define the image location
	 * and position, and then use load() to attempt to load the image.
	 * It will draw to the screen when loading is complete.
	 */
	public class ImageSprite extends Sprite
	{
		public var bitmap:BitmapData;
		public var orbitmap:BitmapData;
		private var wid:int;
		public var hgt:int=100;
		private var r:Sprite;
		private var overrideS:Boolean=false;
		protected var filename:String = "";
		private var xFix:int = 0;
		private var yFix:int = 0;
		private var cb:Function;
		
		public function ImageSprite(){
			cacheAsBitmap = true;
		}
		
		public function givePosFix(x:int,y:int):void{
			xFix=x;
			yFix=y;
		}
		
		/**
		 * Set the position of the sprite relative to the screen.
		 * 
		 * @param x: The x co-ordinate of the leftmost point of the sprite
		 * @param y: The y co-ordinate of the uppermost point of the sprite
		 */
		public function setPosition(x:int, y:int):void{
			this.x=x+xFix;
			this.y=y+yFix;
		}
		/**
		 * Set the width of the shape to be overriden to. Resizes when loaded.
		 * 
		 * @param w: Width
		 * @param h: currently not needed but there for later incase of double resizing needed
		 */
		public function overrideSize(w:int,h:int):void{
			overrideS=true;
			wid=w;
			hgt=h;
		}
		/**
		 * Begin loading of the image, given the specified url.
		 * 
		 * @param render: The Sprite object that the image will display onto.
		 * @param url: The location of the image file, local or otherwise. 
		 */
		public function load(render:Sprite,url:String, callback:Function=null):void{
			graphics.clear();
			r=render;
			filename=url;
			cb = callback;
			var bo=0;
			for (var s =0;s<CONSTANTS.loadedImages.length;s++){
				if (CONSTANTS.loadedImages[s] as String==filename)bo=1;
			}
			if (bo==1){
				trace("SAVED LOADING");
				bitmap= (new Bitmap(CONSTANTS.imageMap[filename] as BitmapData)).bitmapData;
				orbitmap=(new Bitmap(bitmap)).bitmapData;
				var mx:Matrix = new Matrix(1,0,0,1,0,0);
				graphics.beginBitmapFill(bitmap,mx);
				graphics.drawRect(0,0, bitmap.width, bitmap.height);
				graphics.endFill();
				hgt=bitmap.height;
				if (r==null)return;
				r.addChild(this);
				return;
			}			
			loadImage(url);
		}
		public function BitmapScaled(do_source:BitmapData, thumbWidth:Number, thumbHeight:Number):BitmapData {
			var xscale:Number = thumbWidth/do_source.width;
			var yscale:Number = thumbHeight/do_source.height;
			var matrix:Matrix = new Matrix();
			matrix.scale(xscale,yscale);
			var smallBMD:BitmapData = new BitmapData(do_source.width * xscale, do_source.height * yscale, true, 0x000000);
			smallBMD.draw(orbitmap, matrix, null, null, null, true);
			return new Bitmap(smallBMD, PixelSnapping.NEVER, true).bitmapData;
		}
		public function resizeCertain(w:Number,h:Number):void{
			if(orbitmap == null) return;
			graphics.clear();
			bitmap = BitmapScaled(orbitmap,w,h);
			var mx:Matrix = new Matrix(1,0,0,1,0,0);
			graphics.beginBitmapFill(bitmap,mx);
			graphics.drawRect(0,0, bitmap.width, bitmap.height);
			graphics.endFill();
			hgt=h;
			wid=w;
		}
		private function loadImage(url:String):void{
			
			var loader : Loader = new Loader();
			var lc:LoaderContext = new LoaderContext();
			lc.imageDecodingPolicy = ImageDecodingPolicy.ON_LOAD;
			loader.load(new URLRequest(url),lc);
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoadComplete);
		}
		
		/**
		 * This is called when the image has finished loading, and will
		 * display the sprite on the screen at the set position.
		 */
		public function imgLoadComplete(e:Event):void{
			
			bitmap = new Bitmap(e.target.content.bitmapData).bitmapData;
			var mx:Matrix = new Matrix(1,0,0,1,0,0);
			if (overrideS){
				//resizes image if overrideS is true
				var scale:Number = wid/bitmap.width;
				var matrix:Matrix = new Matrix();
				matrix.scale(scale, scale);
				var smallBMD:BitmapData = new BitmapData(bitmap.width * scale, bitmap.height * scale, true, 0x000000);
				smallBMD.draw(bitmap, matrix, null, null, null, true);
				bitmap = new Bitmap(smallBMD, PixelSnapping.NEVER, true).bitmapData;
			}
			orbitmap=(new Bitmap(bitmap)).bitmapData;
			graphics.beginBitmapFill(bitmap,mx);
			graphics.drawRect(0,0, bitmap.width, bitmap.height);
			graphics.endFill();
			CONSTANTS.imageMap[filename]=(new Bitmap(bitmap)).bitmapData;
			CONSTANTS.loadedImages.push(filename);
			hgt=bitmap.height;
			if(cb!=null) cb();
			if (r==null)return;
			r.addChild(this);
		}
	}
}